package com.sinosoft.dsp.system.to.attribute;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.Serializable;

import com.sinosoft.dsp.system.core.exception.SinoFileException;
import com.sinosoft.dsp.system.to.exception.SinoAttributeException;
import com.sinosoft.dsp.system.to.helper.CommonAttributeType;
import com.sinosoft.dsp.system.utils.Const;
import com.sinosoft.dsp.system.utils.StringUtil;

/**
 * 字符串类型
 * 
 * @author 潘巍（Peter Pan）
 * @since 2010-11-9 下午06:22:06
 */
public class StringType extends AbstractType<String> implements Serializable,
		Attribute<String> {

	private static final long serialVersionUID = -643959285930686349L;

	/**
	 * 是否忽略大小写
	 */
	private boolean caseInsensitive;

	public boolean isCaseInsensitive() {
		return caseInsensitive;
	}

	public void setCaseInsensitive(boolean caseInsensitive) {
		this.caseInsensitive = caseInsensitive;
	}

	@Override
	public CommonAttributeType getType() {
		return CommonAttributeType.TYPE_STRING;
	}

	@Override
	public int compare(Attribute<?> attr) throws SinoAttributeException {
		if (attr.getType() != this.getType()) {
			return -1;
		}

		boolean n1 = isNull();
		boolean n2 = true;
		if (attr != null)
			n2 = attr.isNull();

		// null永远最小
		if (n1 && !n2)
			return -1;
		if (!n1 && n2)
			return 1;
		if (n1 && n2)
			return 0;

		int cmp = 0;
		String one = getValue();
		String two = (String) attr.getValue();

		if (caseInsensitive) {
			cmp = one.compareToIgnoreCase(two);
		} else {
			cmp = one.compareTo(two);
		}

		if (isSortedDescending()) {
			return -cmp;
		} else {
			return cmp;
		}
	}

	@Override
	public String readData(DataInputStream inputStream)
			throws SinoFileException {
		try {
			return StringUtil.readString(inputStream);
		} catch (IOException e) {
			throw new SinoFileException(toString() + " : 无法从输入流中读取值数据", e);
		}
	}

	@Override
	public boolean requiresRealClone() {
		return false;
	}

	@Override
	public void writeData(DataOutputStream outputStream)
			throws SinoFileException, SinoAttributeException {
		try {
			outputStream.writeBoolean(isNull());
			String string = getValue();
			if (string == null) {
				outputStream.writeInt(-1);
			} else {
				byte[] chars = string.getBytes(Const.XML_ENCODING);
				outputStream.writeInt(chars.length);
				outputStream.write(chars);
			}
		} catch (ClassCastException e) {
			throw new RuntimeException(toString() + " : 发生数据类型错误 ");
		} catch (IOException e) {
			throw new SinoFileException(toString() + " : 无法从输出流中读取值", e);
		}
	}

	@Override
	public void instantiateFromString(String content)
			throws SinoAttributeException {
		String v = Const.isEmpty(content) ? "" : content;
		this.setValue(v);
	}

	@Override
	public String convertToString() {
		return getValue();
	}

	@Override
	public void instantiateFromObject(Object content)
			throws SinoAttributeException {
		if (content != null) {
			if (content instanceof String) {
				this.setValue((String) content);
			} else {
				throw new SinoAttributeException("通过对象，为StringType属性赋值出现错误：",
						content.toString());
			}
		}
	}

}
